import Tool from './Tool';

interface Cookiefig {
	cookie?: any;
	removeCookie?: any;
	clearCookie?: any;
}
interface Config {
	raw?: any;
	json?: any;
	defaults?: any;
}

let Cookie = function() {
	let Cookie: Cookiefig = {}
	var pluses = /\+/g;

	function encode(s) {
		return config.raw ? s : encodeURIComponent(s);
	}

	function decode(s) {
		return config.raw ? s : decodeURIComponent(s);
	}

	function stringifyCookieValue(value) {
		return encode(config.json ? JSON.stringify(value) : String(value));
	}

	function parseCookieValue(s) {
		if (s.indexOf('"') === 0) {
			// This is a quoted cookie as according to RFC2068, unescape...
			s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
		}

		try {
			// Replace server-side written pluses with spaces.
			// If we can't decode the cookie, ignore it, it's unusable.
			// If we can't parse the cookie, ignore it, it's unusable.
			s = decodeURIComponent(s.replace(pluses, ' '));
			return config.json ? JSON.parse(s) : s;
		} catch (e) { }
	}

	function read(s?:any, converter?:any) {
		var value = config.raw ? s : parseCookieValue(s);
		return typeof converter === 'function' ? converter(value) : value;
	}

	var config: Config = Cookie.cookie = function(key?: any, value?: any, options?: any) {

		// Write

		if (arguments.length > 1 ) {
			options = Tool.assign({}, config.defaults, options);

			if (typeof options.expires === 'number') {
				var days = options.expires, t = options.expires = new Date();
				t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
			}

			return (document.cookie = [
				encode(key), '=', stringifyCookieValue(value),
				options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
				options.path ? '; path=' + options.path : '',
				options.domain ? '; domain=' + options.domain : '',
				options.secure ? '; secure' : ''
			].join(''));
		}

		// Read

		var result = key ? undefined : {},
			// To prevent the for loop in the first place assign an empty array
			// in case there are no cookies at all. Also prevents odd result when
			// calling $.cookie().
			cookies = document.cookie ? document.cookie.split('; ') : [],
			i = 0,
			l = cookies.length;

		for (; i < l; i++) {
			var parts = cookies[i].split('='),
				name = decode(parts.shift()),
				cookie = parts.join('=');

			if (key === name) {
				// If second argument (value) is a function it's a converter...
				result = read(cookie, value);
				break;
			}

			// Prevent storing a cookie that we couldn't decode.
			if (!key && (cookie = read(cookie)) !== undefined) {
				result[name] = cookie;
			}
		}

		return result;
	};

	config.defaults = {};

	Cookie.removeCookie = function(key, options) {
		// Must not alter options, thus extending a fresh object...
		Cookie.cookie(key, '', Tool.assign({}, options, { expires: -1 }));
		return !Cookie.cookie(key);
	};

	Cookie.clearCookie = function() {
		var aCookie = document.cookie.split(";");
		var re = '';
		var exp = new Date();
		exp.setTime(exp.getTime() - 1);
		for (var i = 0; i < aCookie.length; i++) {
			var aCrumb = aCookie[i].split("=");
			document.cookie = aCrumb[0] + "=" + aCrumb[1] + ";path=/;expires=" + exp.toUTCString();
		}
	};

    return Cookie;
};

export default Cookie();